﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Sql;
using System.Linq;
using System.Text;

namespace ZOVNP.WinView
{
    /// <summary> Вспомогательный класс SQL сервера, предоставляющий информацию о доступных серверах(инстанциях) в сети </summary>
    [Description("Вспомогательный класс SQL сервера, предоставляющий информацию о доступных серверах(инстанциях) в сети")]
    public sealed class SQLServerInfo
    {
        /// <summary> Названия колонок таблицы (полей строки) </summary>
        private const string COLUMN_NAME = "ServerName";
        private const string COLUMN_INSTANCENAME = "InstanceName";
        private const string COLUMN_CLUSTERED = "IsClustered";
        private const string COLUMN_VERSION = "Version";

        /// <summary> Имя SQL сервера </summary>
        private readonly string m_name;
        /// <summary> Имя инстанции SQL сервера </summary>
        private readonly string m_instanceName;
        /// <summary> Признак кластера (сервер является частью кластера) </summary>
        private readonly string m_clustered;
        /// <summary> Версия SQL сервера </summary>
        private readonly string m_version;

        /// <summary> Конструктор со строкой таблицы </summary>
        /// <param name="row"> строка таблицы, возвращаемая методом GetDataSources() </param>
        private SQLServerInfo(DataRow row)
        {
            m_name = GetValue(row, COLUMN_NAME);
            m_instanceName = GetValue(row, COLUMN_INSTANCENAME);
            m_clustered = GetValue(row, COLUMN_CLUSTERED);
            m_version = GetValue(row, COLUMN_VERSION);
        }
        /// <summary> Получить строковое название </summary>
        /// <returns> строка </returns>
        public override string ToString()
        {
            string result = m_name;
            if (!String.IsNullOrEmpty(m_instanceName))
                result += @"\" + m_instanceName;
            if (!String.IsNullOrEmpty(m_version))
                result += "      (" + m_version + ")";
            return (result);
        }
        /// <summary> Получить значение из строки таблицы </summary>
        /// <param name="row"> строка </param>
        /// <param name="columnName"> название колонки </param>
        /// <returns> строковое значение </returns>
        private static string GetValue(DataRow row, string columnName)
        {
            string result;
            try { return (result = row[columnName] as string); }
            catch { return (result = "Неизвестно"); }
        }
        /// <summary> Получить имя сервера </summary>
        /// <value> строка с именем </value>
        public string Name { get { return (m_name); } }
        /// <summary> Получить имя инстанции </summary>
        /// <value> строка с именем или null, если инстанция по-умолчанию </value>
        public string InstanceName { get { return (m_instanceName); } }
        /// <summary> Получить признак кластерного сервера </summary>
        /// <value> true, если сервер является частью кластера, в противном случае - false </value>
        public string Clustered { get { return (m_clustered); } }
        /// <summary> Получить версию инстанции </summary>
        /// <value> строка с версией </value>
        public string Version { get { return (m_version); } }
        /// <summary> Получить ключ инстанции </summary>
        /// <value> строка, содержащая имя сервера и инстанции сервера </value>
        public string Key { get { return (IsDefaultInstance ? m_name : (m_name + @"\" + m_instanceName)); } }
        /// <summary> Получить признак инстанции по-умолчанию </summary>
        /// <value> true, если инстанция по-умолчанию, в противном случае - false </value>
        public bool IsDefaultInstance { get { return (String.IsNullOrEmpty(m_instanceName)); } }

        /// <summary> Перечислитель источников данных (SQL серверов) </summary>
        public class DataSourceEnumerator : IEnumerable<SQLServerInfo>
        {
            private List<SQLServerInfo> m_list;

            /// <summary> Получить итератор </summary>
            /// <returns> итератор </returns>
            IEnumerator<SQLServerInfo> IEnumerable<SQLServerInfo>.GetEnumerator() { return (this.List.GetEnumerator()); }
            /// <summary> Получить итератор </summary>
            /// <returns> итератор </returns>
            IEnumerator IEnumerable.GetEnumerator() { return (this.List.GetEnumerator()); }
            /// <summary> Получить список серверов </summary>
            /// <value> список </value>
            private List<SQLServerInfo> List
            {
                get
                {
                    if (m_list == null)
                    {
                        m_list = new List<SQLServerInfo>();
                        DataTable table = SqlDataSourceEnumerator.Instance.GetDataSources();
                        foreach (DataRow row in table.Rows)
                            m_list.Add(new SQLServerInfo(row));
                    }
                    return (m_list);
                }
            }
        }
    }
}
